/******************************************************************************
/// @copyright Copyright (c) 2017 <dji-innovations, Corp. RM Dept.>
/// @license MIT License
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction,including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense,and/or sell
/// copies of the Software, and to permit persons to whom the Software is furnished
/// to do so,subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
///
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
*******************************************************************************/

#include "i2c_oled.h"
#include "mytype.h"
#include "stm32f4xx_hal.h"

#include "cmsis_os.h"
#include "gpio.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

//#define 	USE_GRAPH_RAM	//at least 1024 B RAM space needed!

//#define SCL_1 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET)
//#define SCL_0 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET)
//#define SDA_1 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_SET)
//#define SDA_0 		HAL_GPIO_WritePin(GPIOA, GPIO_PIN_11, GPIO_PIN_RESET)

#define SCL_1 HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_SET)
#define SCL_0 HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_RESET)
#define SDA_1 HAL_GPIO_WritePin(OLED_SDA_GPIO_Port, OLED_SDA_Pin, GPIO_PIN_SET)
#define SDA_0 HAL_GPIO_WritePin(OLED_SDA_GPIO_Port, OLED_SDA_Pin, GPIO_PIN_RESET)

#define XLevelL 0x00
#define XLevelH 0x10
#define XLevel ((XLevelH & 0x0F) * 16 + XLevelL)
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xFF

#define X_WIDTH 128
#define Y_WIDTH 64

#ifdef USE_GRAPH_RAM
uint16_t GlobalRamPointPos = 0;
#endif

const char display_chinese[] = {

    // 按(0) 压(1) 深(2) 度(3) ：(4)

    0x10, 0x10, 0x10, 0xFF, 0xFF, 0xB0, 0xB8, 0x98, 0x88, 0xE9, 0xEF, 0x8E, 0x88, 0xA8, 0xB8, 0x98,
    0x02, 0x42, 0xC3, 0xFF, 0x7F, 0x00, 0x80, 0x84, 0xCF, 0x6B, 0x38, 0x38, 0x6F, 0xC7, 0x80, 0x00, /*"按",0*/

    0x00, 0x00, 0xFE, 0xFE, 0x82, 0x82, 0x82, 0x82, 0xFA, 0xFA, 0x82, 0x82, 0x82, 0x82, 0x82, 0x02,
    0x80, 0xE0, 0x7F, 0x5F, 0x40, 0x40, 0x40, 0x40, 0x7F, 0x7F, 0x40, 0x44, 0x5C, 0x58, 0x40, 0x40, /*"压",1*/

    0x10, 0x70, 0x62, 0x8E, 0x8C, 0x0E, 0x2E, 0x32, 0x1A, 0xCA, 0xCA, 0x1A, 0x32, 0x2E, 0x0E, 0x00,
    0x04, 0x04, 0x7E, 0x7F, 0x21, 0x21, 0x31, 0x19, 0x0D, 0xFF, 0xFF, 0x0D, 0x19, 0x31, 0x21, 0x20, /*"深",2*/

    0x00, 0x00, 0xFC, 0xFC, 0x24, 0x24, 0xFC, 0xFD, 0x27, 0x26, 0xFC, 0xFC, 0x24, 0x24, 0x24, 0x04,
    0x40, 0x70, 0xBF, 0x8F, 0x84, 0xCC, 0x5D, 0x75, 0x25, 0x25, 0x75, 0x5D, 0xCC, 0x80, 0x80, 0x80, /*"度",3*/

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"：",4*/
};

#ifdef USE_GRAPH_RAM
unsigned char GRAM[1024];
#endif
const unsigned char logoUESTC[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0,
    0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0x78, 0xFC, 0x9C,
    0x04, 0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
    0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x3C,
    0x1C, 0x3C, 0x38, 0x18, 0xB8, 0xF0, 0xF0, 0xE0,
    0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0,
    0xB0, 0x3C, 0x7E, 0xFE, 0x7F, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0x38, 0x38, 0x1F,
    0x1E, 0x0E, 0x08, 0x0F, 0x0F, 0x07, 0x07, 0x07,
    0x07, 0x07, 0x07, 0x0F, 0x0F, 0x0E, 0x0E, 0x1C,
    0x18, 0x38, 0x30, 0x6E, 0x7F, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xF8,
    0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0xC0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFE, 0xF8, 0xFA, 0x78, 0x1F, 0x07,
    0x03, 0x01, 0x00, 0xF0, 0x18, 0x08, 0x08, 0x08,
    0x08, 0x08, 0x18, 0x10, 0x10, 0x30, 0x20, 0xA0,
    0xC0, 0xC0, 0x60, 0x20, 0x30, 0x10, 0x10, 0x08,
    0x08, 0x08, 0x08, 0x08, 0x18, 0xF0, 0x01, 0x03,
    0x07, 0x1F, 0x3F, 0xF7, 0xF1, 0x31, 0xF3, 0xE1,
    0xE9, 0xFD, 0xFF, 0xFE, 0xF8, 0xC0, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0xFE, 0x7F, 0x7F, 0xBF, 0x3F, 0x7F, 0xFF,
    0xFF, 0x7F, 0xFF, 0x0F, 0x01, 0x00, 0xC0, 0xC0,
    0x00, 0x00, 0xC0, 0xC3, 0x04, 0xE8, 0x80, 0x30,
    0x10, 0x50, 0x10, 0x30, 0xEC, 0xC6, 0x03, 0x01,
    0xC1, 0xE0, 0x21, 0x43, 0x06, 0x0C, 0x28, 0x20,
    0xE0, 0x60, 0x20, 0x10, 0x0C, 0xC7, 0x60, 0x20,
    0x60, 0x40, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x7F,
    0xFF, 0xBF, 0x3F, 0xFF, 0xBF, 0xFF, 0xFE, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xF8, 0xF8,
    0xFD, 0xFE, 0xFF, 0xF0, 0x00, 0x00, 0x03, 0x07,
    0x04, 0x04, 0x07, 0x03, 0xE0, 0x13, 0x04, 0x08,
    0x0A, 0x0A, 0x1A, 0x1E, 0x37, 0x63, 0xC0, 0x80,
    0x02, 0x04, 0x85, 0xC7, 0x62, 0x30, 0x30, 0x10,
    0x07, 0x02, 0x04, 0x08, 0x10, 0xE3, 0x06, 0x04,
    0x06, 0x02, 0x00, 0x00, 0xE0, 0xFF, 0xFC, 0xFC,
    0xF8, 0xFC, 0xFC, 0xFC, 0xFF, 0xF9, 0x7F, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x03, 0x1F, 0x7F, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xF0, 0xE0,
    0xC0, 0x80, 0x00, 0x00, 0x0F, 0x10, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x04, 0x06,
    0x02, 0x03, 0x05, 0x04, 0x08, 0x08, 0x10, 0x10,
    0x10, 0x10, 0x10, 0x10, 0x10, 0x0F, 0x80, 0xC0,
    0xE0, 0xF0, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0x7F, 0x1F, 0x03, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07,
    0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xF8, 0xF8,
    0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
    0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF0,
    0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F,
    0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07,
    0x07, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F,
    0x37, 0x78, 0x7E, 0x77, 0x71, 0x72, 0x78, 0x7E,
    0x73, 0x74, 0x78, 0x7E, 0x73, 0x71, 0x70, 0x3A,
    0x3F, 0x3F, 0x1F, 0x1F, 0x1F, 0x0F, 0x0F, 0x07,
    0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}; //8line 64 colums

const unsigned char F6x8[][6] = {
    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp
    { 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !
    { 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
    { 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
    { 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
    { 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // %
    { 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
    { 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
    { 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
    { 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
    { 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, // *
    { 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
    { 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // ,
    { 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
    { 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
    { 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
    { 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
    { 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
    { 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
    { 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3
    { 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4
    { 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
    { 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
    { 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
    { 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
    { 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
    { 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
    { 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
    { 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
    { 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
    { 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
    { 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
    { 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @
    { 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A
    { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B
    { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C
    { 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D
    { 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E
    { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F
    { 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G
    { 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H
    { 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I
    { 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J
    { 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K
    { 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L
    { 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M
    { 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N
    { 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O
    { 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P
    { 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q
    { 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R
    { 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
    { 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T
    { 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U
    { 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V
    { 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
    { 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
    { 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
    { 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
    { 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [
    { 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55
    { 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]
    { 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
    { 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
    { 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // '
    { 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
    { 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b
    { 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
    { 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d
    { 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
    { 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f
    { 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g
    { 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
    { 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
    { 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j
    { 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k
    { 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l
    { 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m
    { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n
    { 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
    { 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p
    { 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q
    { 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r
    { 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
    { 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t
    { 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u
    { 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v
    { 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w
    { 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
    { 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y
    { 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z
    { 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 }, // horiz lines
};
const unsigned char F32x16_NUM_TAB[] = {
    // 0(0) 1(1) 2(2) 3(3) 4(4) 5(5) 6(6) 7(7) 8(8) 9(9) .(10)

    0x00, 0x00, 0xC0, 0xE0, 0xF0, 0x30, 0x18, 0x08, 0x08, 0x08, 0x08, 0x18, 0x38, 0xF0, 0xE0, 0xC0,
    0x00, 0x00, 0x07, 0x0F, 0x1F, 0x18, 0x30, 0x20, 0x20, 0x20, 0x20, 0x30, 0x18, 0x1F, 0x0F, 0x07, /*"0",0*/

    0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0xF0, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x3F, 0x3F, 0x3F, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, /*"1",1*/

    0x00, 0x00, 0x60, 0x70, 0x50, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x98, 0xF8, 0xF0, 0x70, 0x00,
    0x00, 0x00, 0x20, 0x30, 0x38, 0x28, 0x2C, 0x24, 0x26, 0x22, 0x23, 0x21, 0x30, 0x38, 0x18, 0x00, /*"2",2*/

    0x00, 0x00, 0x30, 0x30, 0x38, 0x08, 0x88, 0x88, 0x88, 0x88, 0xD8, 0x78, 0x70, 0x30, 0x00, 0x00,
    0x00, 0x00, 0x18, 0x18, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x1F, 0x1F, 0x0E, 0x00, /*"3",3*/

    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0xF0, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
    0x00, 0x04, 0x06, 0x07, 0x05, 0x05, 0x24, 0x24, 0x24, 0x3F, 0x3F, 0x3F, 0x3F, 0x24, 0x24, 0x24, /*"4",4*/

    0x00, 0x00, 0x00, 0xC0, 0xF8, 0xB8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x08, 0x08, 0x00,
    0x00, 0x00, 0x18, 0x39, 0x29, 0x21, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x1F, 0x1F, 0x0E, 0x00, /*"5",5*/

    0x00, 0x00, 0x80, 0xE0, 0xF0, 0x30, 0x98, 0x98, 0x88, 0x88, 0x88, 0x88, 0x98, 0x98, 0x10, 0x00,
    0x00, 0x00, 0x07, 0x0F, 0x1F, 0x39, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x1F, 0x1F, 0x0E, /*"6",6*/

    0x00, 0x00, 0x30, 0x38, 0x18, 0x08, 0x08, 0x08, 0x08, 0x88, 0xC8, 0x68, 0x38, 0x18, 0x08, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3E, 0x3F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*"7",7*/

    0x00, 0x00, 0x70, 0x70, 0xF8, 0xD8, 0x88, 0x88, 0x08, 0x08, 0x08, 0x98, 0xF8, 0x70, 0x70, 0x00,
    0x00, 0x0C, 0x1E, 0x1E, 0x33, 0x21, 0x21, 0x21, 0x21, 0x21, 0x23, 0x33, 0x1E, 0x1E, 0x0C, 0x00, /*"8",8*/

    0x00, 0xE0, 0xF0, 0xF0, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x18, 0xF0, 0xF0, 0xC0, 0x00,
    0x00, 0x00, 0x11, 0x33, 0x33, 0x22, 0x22, 0x22, 0x22, 0x32, 0x33, 0x1D, 0x1F, 0x0F, 0x03, 0x00, /*"9",9*/

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*".",10*/

};
const char F16x16[] = {
    // 测(0) 试(1) 程(2) 序(3)
    0x00, 0x00, 0x00, 0x40, 0xC0, 0x50, 0x4E, 0xE8,
    0x58, 0xA8, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x40, 0x20, 0x11, 0x0A, 0x06, 0x19,
    0x27, 0x41, 0x44, 0x48, 0x40, 0x70, 0x20, 0x00, /*"兔",0列行，逆向*/

    0x00, 0x40, 0x40, 0x40, 0xC4, 0x64, 0x40, 0x40,
    0xC0, 0x40, 0xFE, 0xA0, 0x20, 0xE0, 0x20, 0x00,
    0x00, 0x08, 0x04, 0x02, 0x1F, 0x01, 0x01, 0x00,
    0x03, 0x05, 0xFF, 0x02, 0x02, 0x01, 0x00, 0x00, /*"神",1列行，逆向*/

    0x00, 0x00, 0x80, 0x78, 0xE8, 0x28, 0xD8, 0x8C,
    0x40, 0x38, 0x08, 0xB8, 0x40, 0x40, 0x00, 0x00,
    0x20, 0x18, 0x07, 0x25, 0x1B, 0x05, 0x0B, 0x1A,
    0x22, 0x26, 0x19, 0x1F, 0x21, 0x20, 0x40, 0x00, /*"殿",2列行，逆向*/

    0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x08, 0xF8,
    0x88, 0x88, 0x88, 0x08, 0x08, 0x08, 0x08, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F,
    0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, /*"下",3列行，逆向*/
};

static void delay(unsigned int z);

/////////////////////////////////////////////OLED CTR///
/*********************OLED驱动程序用的延时程序************************************/
static void OLED_GPIO_config()
{
    //	GPIO_InitTypeDef GPIO_InitStructure;
    //	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    //
    //	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    //	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    //	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    //	GPIO_Init(GPIOB,&GPIO_InitStructure);
}

static void delay(unsigned int z)
{
    unsigned int x, y;
    for (x = z; x > 0; x--)
        for (y = 1; y > 0; y--)
            ;
}

/**********************************************
//IIC Start
**********************************************/
static void IIC_Start()
{
    SCL_1;
    delay(5);
    SDA_1;
    delay(5);
    SDA_0;
    delay(5);
    SCL_0;
    delay(5);
}

/**********************************************
//IIC Stop
**********************************************/
static void IIC_Stop()
{
    SCL_0;
    delay(5);
    SDA_0;
    delay(5);
    SCL_1;
    delay(5);
    SDA_1;
    delay(5);
}

/**********************************************
// 通过I2C总线写一个字节
**********************************************/
void Write_IIC_Byte(unsigned char IIC_Byte)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
        if (IIC_Byte & 0x80)
            SDA_1;
        else
            SDA_0;
        delay(5);
        SCL_1;
        delay(5);
        SCL_0;
        delay(5);
        IIC_Byte <<= 1;
    }
    SDA_1;
    delay(5);
    SCL_1;
    delay(5);
    SCL_0;
    delay(5);
}

/*********************OLED写数据************************************/
void OLED_WrDat(unsigned char IIC_Data)
{
    IIC_Start();
    Write_IIC_Byte(0x78); //0111100->Slave address, 0->SA0=0
    Write_IIC_Byte(0x40); //write data
    Write_IIC_Byte(IIC_Data);
    IIC_Stop();
}
/*********************OLED写命令************************************/
void OLED_WrCmd(unsigned char IIC_Command)
{
    IIC_Start();
    Write_IIC_Byte(0x78); //0111100->Slave address, 0->SA0=0
    Write_IIC_Byte(0x00); //write command
    Write_IIC_Byte(IIC_Command);
    IIC_Stop();
}
/*********************OLED 设置坐标************************************/
void oled_set_pos(unsigned char x, unsigned char y)
{
#ifdef USE_GRAPH_RAM
    GlobalRamPointPos = x + y * 128;
#else
    OLED_WrCmd(0xb0 + y); //设置page，范围b0~b7
    OLED_WrCmd(((x & 0xf0) >> 4) | 0x10); //set the upper column address
    OLED_WrCmd((x & 0x0f) | 0x01); //set the lower column address
#endif
}

/************write virtual graph ram to oled to reflash************************/
void oled_reflash(unsigned char* ram)
{
    unsigned char y, x;
    for (y = 0; y < 8; y++)
    {
        OLED_WrCmd(0xb0 + y);
        OLED_WrCmd(0x01);
        OLED_WrCmd(0x10);
        //while(*bmp_dat!='\0')
        for (x = 0; x < X_WIDTH; x++)
            OLED_WrDat(*ram++);
    }
}

void oled_fill(unsigned char* bmp_dat)
{
    unsigned char y, x;
    for (y = 0; y < 8; y++)
    {
        OLED_WrCmd(0xb0 + y);
        OLED_WrCmd(0x01);
        OLED_WrCmd(0x10);
        //while(*bmp_dat!='\0')
        for (x = 0; x < X_WIDTH; x++)
            OLED_WrDat(*bmp_dat++);
    }
}
/*********************OLED复位************************************/
void oled_clear_screen(void)
{
#ifdef USE_GRAPH_RAM
    memset(GRAM, 0, 1024);

#else
    unsigned char y, x;
    for (y = 0; y < 8; y++)
    {
        OLED_WrCmd(0xb0 + y);
        OLED_WrCmd(0x01);
        OLED_WrCmd(0x10);
        for (x = 0; x < X_WIDTH; x++)
            OLED_WrDat(0);
    }
#endif
}
/*********************OLED初始化************************************/
void oled_init(void)
{
    OLED_GPIO_config();
    delay(500); //初始化之前的延时很重要！

    OLED_WrCmd(0xae); //--turn off oled panel
    OLED_WrCmd(0x00); //---set low column address
    OLED_WrCmd(0x10); //---set high column address
    OLED_WrCmd(0x40); //--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
    OLED_WrCmd(0x81); //--set contrast control register
    OLED_WrCmd(Brightness); // Set SEG Output Current Brightness
    OLED_WrCmd(0xa1); //--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
    OLED_WrCmd(0xc8); //Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
    OLED_WrCmd(0xa6); //--set normal display
    OLED_WrCmd(0xa8); //--set multiplex ratio(1 to 64)
    OLED_WrCmd(0x3f); //--1/64 duty
    OLED_WrCmd(0xd3); //-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
    OLED_WrCmd(0x00); //-not offset
    OLED_WrCmd(0xd5); //--set display clock divide ratio/oscillator frequency
    OLED_WrCmd(0x80); //--set divide ratio, Set Clock as 100 Frames/Sec
    OLED_WrCmd(0xd9); //--set pre-charge period
    OLED_WrCmd(0xf1); //Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    OLED_WrCmd(0xda); //--set com pins hardware configuration
    OLED_WrCmd(0x12);
    OLED_WrCmd(0xdb); //--set vcomh
    OLED_WrCmd(0x40); //Set VCOM Deselect Level
    OLED_WrCmd(0x20); //-Set Page Addressing Mode (0x00/0x01/0x02)
    OLED_WrCmd(0x02); //
    OLED_WrCmd(0x8d); //--set Charge Pump enable/disable
    OLED_WrCmd(0x14); //--set(0x10) disable
    OLED_WrCmd(0xa4); // Disable Entire Display On (0xa4/0xa5)
    OLED_WrCmd(0xa6); // Disable Inverse Display On (0xa6/a7)
    OLED_WrCmd(0xaf); //--turn on oled panel
    oled_fill(0x00); //初始清屏
    oled_set_pos(0, 0);
}

void oled_printf(unsigned char x, unsigned char y, const char* fmt, ...)
{
    //oled_set_pos(x, y);
    char      buff[128] = { 0 };
    __va_list ap;
    va_start(ap, fmt);
    vsprintf(buff, fmt, ap);

    oled_p6x8str(0, x, y, buff);
    va_end(ap);
}


/*****功能描述：显示32x16的1个数字，显示的坐标（x,y），y为页范围0～7******/
/*num 取值从 0 -- 9 */
void oled_p16x16num(const unsigned char x, const unsigned char y,
                    const unsigned char num)
{
    const unsigned char* p = F32x16_NUM_TAB;
    if (x > 128)
        return;
    if (y > 7)
        return;
    if (num > 10)
        return;

    p += 32 * num; //pointer offset
    oled_set_pos(x, y);
    for (u8 i = 0; i < 16; i++)
    {
        OLED_WrDat(*p++);
    }
    //上半个字
    oled_set_pos(x, y + 1);
    for (u8 i = 0; i < 16; i++)
    {
        OLED_WrDat(*p++);
    }
}
/***************功能描述：显示16x16一组汉字	显示的坐标（x,y），y为页范围0～7****************/
/*所需汉字需已经存表,一行最多八个字,列行式
显示从index开始的num个数，传入数组名*/
void oled_p16x16ch(unsigned char x, const unsigned char y,
                   const unsigned char index, const unsigned char num,
                   const char* p)
{
    unsigned char i;
    if (x > 128)
        return;
    if (y > 7)
        return;
    if (num > 8)
        return;
    p += index * 32; //set pointer position, one chinese use 32 byte!
    for (u8 j = 0; j < num - index; j++)
    {
        oled_set_pos(x + 16 * j, y);
        for (i = 0; i < 16; i++)
        {
            OLED_WrDat(*(p++));
        }
        oled_set_pos(x + 16 * j, y + 1);
        for (i = 0; i < 16; i++)
        {
            OLED_WrDat(*(p++));
        }
    }
}
